{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PRatioEncoder\n",
    "\n",
    "The PRatioEncoder() replaces categories by the ratio of the probability of the\n",
    "target = 1 and the probability of the target = 0.<br>\n",
    "\n",
    "The target probability ratio is given by: p(1) / p(0).\n",
    "\n",
    "The log of the target probability ratio is: np.log( p(1) / p(0) )\n",
    "#### It only works for binary classification."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "from feature_engine.encoding import PRatioEncoder\n",
    "\n",
    "from feature_engine.encoding import RareLabelEncoder #to reduce cardinality"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load titanic dataset from OpenML\n",
    "\n",
    "def load_titanic():\n",
    "    data = pd.read_csv('https://www.openml.org/data/get_csv/16826755/phpMYEkMl')\n",
    "    data = data.replace('?', np.nan)\n",
    "    data['cabin'] = data['cabin'].astype(str).str[0]\n",
    "    data['pclass'] = data['pclass'].astype('O')\n",
    "    data['age'] = data['age'].astype('float')\n",
    "    data['fare'] = data['fare'].astype('float')\n",
    "    data['embarked'].fillna('C', inplace=True)\n",
    "    data.drop(labels=['boat', 'body', 'home.dest'], axis=1, inplace=True)\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pclass</th>\n",
       "      <th>survived</th>\n",
       "      <th>name</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>ticket</th>\n",
       "      <th>fare</th>\n",
       "      <th>cabin</th>\n",
       "      <th>embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Allen, Miss. Elisabeth Walton</td>\n",
       "      <td>female</td>\n",
       "      <td>29.0000</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>24160</td>\n",
       "      <td>211.3375</td>\n",
       "      <td>B</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Allison, Master. Hudson Trevor</td>\n",
       "      <td>male</td>\n",
       "      <td>0.9167</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Allison, Miss. Helen Loraine</td>\n",
       "      <td>female</td>\n",
       "      <td>2.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Allison, Mr. Hudson Joshua Creighton</td>\n",
       "      <td>male</td>\n",
       "      <td>30.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Allison, Mrs. Hudson J C (Bessie Waldo Daniels)</td>\n",
       "      <td>female</td>\n",
       "      <td>25.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  pclass  survived                                             name     sex  \\\n",
       "0      1         1                    Allen, Miss. Elisabeth Walton  female   \n",
       "1      1         1                   Allison, Master. Hudson Trevor    male   \n",
       "2      1         0                     Allison, Miss. Helen Loraine  female   \n",
       "3      1         0             Allison, Mr. Hudson Joshua Creighton    male   \n",
       "4      1         0  Allison, Mrs. Hudson J C (Bessie Waldo Daniels)  female   \n",
       "\n",
       "       age  sibsp  parch  ticket      fare cabin embarked  \n",
       "0  29.0000      0      0   24160  211.3375     B        S  \n",
       "1   0.9167      1      2  113781  151.5500     C        S  \n",
       "2   2.0000      1      2  113781  151.5500     C        S  \n",
       "3  30.0000      1      2  113781  151.5500     C        S  \n",
       "4  25.0000      1      2  113781  151.5500     C        S  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = load_titanic()\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = data.drop(['survived', 'name', 'ticket'], axis=1)\n",
    "y = data.survived"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "cabin       0\n",
       "pclass      0\n",
       "embarked    0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# we will encode the below variables, they have no missing values\n",
    "X[['cabin', 'pclass', 'embarked']].isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "cabin       object\n",
       "pclass      object\n",
       "embarked    object\n",
       "dtype: object"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "''' Make sure that the variables are type (object).\n",
    "if not, cast it as object , otherwise the transformer will either send an error (if we pass it as argument) \n",
    "or not pick it up (if we leave variables=None). '''\n",
    "\n",
    "X[['cabin', 'pclass', 'embarked']].dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((916, 8), (393, 8))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# let's separate into training and testing set\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)\n",
    "\n",
    "X_train.shape, X_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Rare value encoder first to reduce the cardinality\n",
    "# see RareLabelEncoder jupyter notebook for more details on this encoder\n",
    "rare_encoder = RareLabelEncoder(tol=0.03,\n",
    "                                n_categories=2, \n",
    "                                variables=['cabin', 'pclass', 'embarked'])\n",
    "\n",
    "rare_encoder.fit(X_train)\n",
    "\n",
    "# transform\n",
    "train_t = rare_encoder.transform(X_train)\n",
    "test_t = rare_encoder.transform(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The PRatioEncoder() replaces categories by the ratio of the probability of the\n",
    "target = 1 and the probability of the target = 0.\n",
    "\n",
    "The target probability ratio is given by: p(1) / p(0)\n",
    "\n",
    "The log of the target probability ratio is: np.log( p(1) / p(0) )\n",
    "\n",
    "Note: This categorical encoding is exclusive for binary classification.\n",
    "\n",
    "For example in the variable colour, if the mean of the target = 1 for blue\n",
    "is 0.8 and the mean of the target = 0  is 0.2, blue will be replaced by:\n",
    "0.8 / 0.2 = 4 if ratio is selected, or log(0.8/0.2) = 1.386 if log_ratio\n",
    "is selected.\n",
    "\n",
    "Note: the division by 0 is not defined and the log(0) is not defined.\n",
    "Thus, if p(0) = 0 for the ratio encoder, or either p(0) = 0 or p(1) = 0 for\n",
    "log_ratio, in any of the variables, the encoder will return an error.\n",
    "\n",
    "The encoder will encode only categorical variables (type 'object'). A list\n",
    "of variables can be passed as an argument. If no variables are passed as\n",
    "argument, the encoder will find and encode all categorical variables\n",
    "(object type)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ratio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PRatioEncoder(variables=['cabin', 'pclass', 'embarked'])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'''\n",
    "Parameters\n",
    "----------\n",
    "\n",
    "encoding_method : str, default=woe\n",
    "    Desired method of encoding.\n",
    "\n",
    "    'ratio' : probability ratio\n",
    "\n",
    "    'log_ratio' : log probability ratio\n",
    "\n",
    "variables : list, default=None\n",
    "    The list of categorical variables that will be encoded. If None, the\n",
    "    encoder will find and select all object type variables.\n",
    "'''\n",
    "Ratio_enc = PRatioEncoder(encoding_method='ratio',\n",
    "                           variables=['cabin', 'pclass', 'embarked'])\n",
    "\n",
    "# to fit you need to pass the target y\n",
    "Ratio_enc.fit(train_t, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'cabin': {'B': 3.1999999999999993,\n",
       "  'C': 1.2903225806451615,\n",
       "  'D': 2.5555555555555554,\n",
       "  'E': 2.5555555555555554,\n",
       "  'Rare': 1.3124999999999998,\n",
       "  'n': 0.4385245901639344},\n",
       " 'pclass': {1: 1.6136363636363635,\n",
       "  2: 0.7735849056603774,\n",
       "  3: 0.34959349593495936},\n",
       " 'embarked': {'C': 1.2625000000000002,\n",
       "  'Q': 0.5961538461538461,\n",
       "  'S': 0.5127610208816704}}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Ratio_enc.encoder_dict_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pclass</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>fare</th>\n",
       "      <th>cabin</th>\n",
       "      <th>embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>442</th>\n",
       "      <td>0.773585</td>\n",
       "      <td>male</td>\n",
       "      <td>24.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>73.5000</td>\n",
       "      <td>0.438525</td>\n",
       "      <td>0.512761</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>358</th>\n",
       "      <td>0.773585</td>\n",
       "      <td>female</td>\n",
       "      <td>42.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13.0000</td>\n",
       "      <td>0.438525</td>\n",
       "      <td>0.512761</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1130</th>\n",
       "      <td>0.349593</td>\n",
       "      <td>female</td>\n",
       "      <td>18.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.7750</td>\n",
       "      <td>0.438525</td>\n",
       "      <td>0.512761</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>113</th>\n",
       "      <td>1.613636</td>\n",
       "      <td>female</td>\n",
       "      <td>23.0</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>263.0000</td>\n",
       "      <td>1.290323</td>\n",
       "      <td>0.512761</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>108</th>\n",
       "      <td>1.613636</td>\n",
       "      <td>female</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>110.8833</td>\n",
       "      <td>0.438525</td>\n",
       "      <td>1.262500</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        pclass     sex   age  sibsp  parch      fare     cabin  embarked\n",
       "442   0.773585    male  24.0      2      0   73.5000  0.438525  0.512761\n",
       "358   0.773585  female  42.0      0      0   13.0000  0.438525  0.512761\n",
       "1130  0.349593  female  18.0      0      0    7.7750  0.438525  0.512761\n",
       "113   1.613636  female  23.0      3      2  263.0000  1.290323  0.512761\n",
       "108   1.613636  female   NaN      0      0  110.8833  0.438525  1.262500"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# transform and visualise the data\n",
    "\n",
    "train_t = Ratio_enc.transform(train_t)\n",
    "test_t = Ratio_enc.transform(test_t)\n",
    "\n",
    "test_t.sample(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### log ratio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PRatioEncoder(encoding_method='log_ratio',\n",
       "              variables=['cabin', 'pclass', 'embarked'])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_t = rare_encoder.transform(X_train)\n",
    "test_t = rare_encoder.transform(X_test)\n",
    "\n",
    "logRatio_enc = PRatioEncoder(encoding_method='log_ratio',\n",
    "                           variables=['cabin', 'pclass', 'embarked'])\n",
    "\n",
    "# to fit you need to pass the target y\n",
    "logRatio_enc.fit(train_t, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'cabin': {'B': 1.1631508098056806,\n",
       "  'C': 0.2548922496287902,\n",
       "  'D': 0.9382696385929302,\n",
       "  'E': 0.9382696385929302,\n",
       "  'Rare': 0.2719337154836416,\n",
       "  'n': -0.8243393908312957},\n",
       " 'pclass': {1: 0.4784902431230542,\n",
       "  2: -0.25671984684781396,\n",
       "  3: -1.0509842396788551},\n",
       " 'embarked': {'C': 0.23309388216737797,\n",
       "  'Q': -0.5172565140962812,\n",
       "  'S': -0.6679453885859952}}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logRatio_enc.encoder_dict_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pclass</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>fare</th>\n",
       "      <th>cabin</th>\n",
       "      <th>embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>649</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>male</td>\n",
       "      <td>23.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.0500</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1217</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>male</td>\n",
       "      <td>19.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.6500</td>\n",
       "      <td>0.271934</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>271</th>\n",
       "      <td>0.478490</td>\n",
       "      <td>male</td>\n",
       "      <td>24.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>82.2667</td>\n",
       "      <td>1.163151</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>948</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>male</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.7500</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.517257</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>934</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>female</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>22.0250</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        pclass     sex   age  sibsp  parch     fare     cabin  embarked\n",
       "649  -1.050984    male  23.0      0      0   7.0500 -0.824339 -0.667945\n",
       "1217 -1.050984    male  19.0      0      0   7.6500  0.271934 -0.667945\n",
       "271   0.478490    male  24.0      1      0  82.2667  1.163151 -0.667945\n",
       "948  -1.050984    male   NaN      0      0   7.7500 -0.824339 -0.517257\n",
       "934  -1.050984  female   4.0      0      2  22.0250 -0.824339 -0.667945"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# transform and visualise the data\n",
    "\n",
    "train_t = logRatio_enc.transform(train_t)\n",
    "test_t = logRatio_enc.transform(test_t)\n",
    "\n",
    "test_t.sample(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbkAAAFNCAYAAACdVxEnAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3deZwddZ3v/9c7nYXsSWeDJJ10A4EQIMTQ3UFlAEEUUImCsujgbsxVXH4zekXvHUWdO+CMd64bTn4Zh+HizMgmalQUHRVwhiXdgQQIixNIQncSyNLZ905/7h9V3RyaXk5CV3e6zvv5ePQjp6q+VfWpc07O51Sdb30/igjMzMzyaEBfB2BmZpYVJzkzM8stJzkzM8stJzkzM8stJzkzM8stJzkzM8stJznrkqT7JH30CNedJmmXpLKejqtgH9dL+pculq+UdN4RbjsknXjEweVUf31eJFWmsQ/s61is9zjJlQBJayTtTRPOi5JukTQio/28uXU6Il6IiBERcain91WsiDg1Iu7r7f3210RQytq/f0tt/3nlJFc63hERI4A5wOuAL/ZxPGa5kuUVCztyTnIlJiJeBO4lSXYASDpL0oOStkla0dnlPUknSPq9pC2SNkv6V0lj0mU/BKYBP0/PGP97+8tDkiZLWiKpSdIqSR8r2Pb1ku6QdKuknellxuqC5V+QtC5d9qykCwpCG9zFem3fjtN93CXp9rTto5LO6OYpu0TS8+nx/p2ktv8zkj4s6WlJWyXdK2l6Ov+BtMmK9Lm4UtL9ki5Pl5+dPi+XpNNvlrS8u+2my2ZK+m36HD4r6YqCZbdIuknSL9Pje0TSCZ28lq2vzQJJ6yVtkPSXBcvLJH1J0nPptpZJquhgO2+T9JikHZIaJF1fsOwYSf+Svl+2SaqTNCld9sH0ed0pabWk93USZ62kh9L1N0j6nqTBBctD0kJJ/5U+XzdJUsExfDN97Z4H3tbhK0zH7990/p1Krn5sl/SApFPbPd//IOkeSbuBN0mamz4fO9N1b5f01wXrvF3S8vR4HpQ0u6v9Ww+ICP/l/A9YA7w5fTwVeAL4djo9BdgCXELypefCdHpCuvw+4KPp4xPT5UOACcADwLc62k86XQkEMDCdvh/4PnAMSZLdBFyQLrse2JfGUQbcADycLjsZaAAmF2z3hO7W6+DYrwcOAu8GBgGfA1YDgzp53gL4A1BO8gH0p4Ln4p3AKuAUYCDwP4EH2617YsH014Dvpo+/BDwHfKNg2be72y4wPH0ePpQumwtsBk5Nl98CNAG16fJ/BW7r5NhaX5sfpds9PX09Wp+rz5O8T04GBJwBjGt/bMB56boDgNnAS8A702UfB34ODEtfmzOBUen+dgAnp+2Oaz2GDuI8EzgrPZ5K4Gngs+2e518AY9LXaBNwUbpsIfAMUJG+hn+g4P3Y1f+TgnkfBkaSvOe/BSwvWHYLsB14Y3r8o4C1wGdI3l+XAQeAv07bzwU2AvPS5+MD6T6HdLZ///XA519fB+C/XniRk/88u4Cd6X/y3wFj0mVfAH7Yrv29wAfSx/eRfrB3sN13Ao+120+HSS79oDkEjCxYfgNwS/r4euDfC5bNAvamj09MPxzeTLuE1NV67WNK2xYmwAHABuDPOjm+aP3ATKc/Afwuffwr4CPttrUHmF6wbmGSuwB4PH38a+CjvJzE7wcu6267wJXAH9vF+P8DX0kf3wL8oGDZJcAznRxb62szs2De3wL/lD5+FpjfxfNyYifLvgX8n/Txh4EHgdnt2gwHtgGXA0MP8738WeAn7WI5u2D6DuC69PHvgYUFy97CYSa5dsvHpOuPLni+by1Yfg6wDlDBvP/g5ST3D8DX223zWeDcYvbvvyP78+XK0vHOiBhJ8s17JjA+nT8deE96+WSbpG3A2STfrl9B0kRJtym5bLgD+JeC7XRnMtAUETsL5q0lOZNs9WLB4z3AMZIGRsQqkg+364GNaQyTu1uvkzgaWh9ERAvQmMbWmYaCx2sL2k4Hvl3wnDWRnPFMoWMPASell+vmALcCFZLGk5x5tV7i7Gq704F57V6r9wHHFuyn/XPRXQejzo6vguRss0uS5kn6g6RNkraTnD21vid+SPKF6bb0kujfShoUEbtJEvZCYEN6eXVmJ9s/SdIv0kuGO4C/4dXvuc6OeXIHx1e09HLnjekl2x0kSYh2+y/c/mRgXaQZq4Pl04G/bPf6VdD1+89eIye5EhMR95N8A/1mOquB5ExuTMHf8Ii4sYPVbyD5Jjs7IkYBf07yAdy2+S52vR4olzSyYN40km++xcT9bxFxNskHRQDfKGa9DrT9rqTk97WpaWzdtieJt7VtA/Dxds/b0Ih4sJP49wDLSC5lPRkRB0jOcv4CeC4iNhex3Qbg/nbLRkTEfzvsZ6G44+vw97x2/g1YAlRExGhgEel7IiIORsRXI2IW8Abg7cD702X3RsSFJF+mngH+sZPt/0O6fEb6nvsSr3zPdWVDB8fXlfbv3/cC80muIIwmOfuFzt/zG4Aprb8Jpgr33wD8r3av37CI+FEn+7ce4CRXmr4FXChpDsnZ2DskvTX95nqMpPMkTe1gvZEklz23SZpC8rtNoZeA4zvaYUQ0kHyo35DuYzbwEZLfjbok6WRJ50saQvL7216SS59H4kxJl6Vnep8F9gMPd9H+85LGpp0uPgPcns5fBHyxtSOCpNGS3lOwXkfPxf3Atem/kFwKLpzubru/IDkbvEbSoPSvRtIpRR/9q/2VpGHp/j5UcHw/AL4uaYYSsyWN62D9kSRn6Psk1ZIkBtLY3yTpdCW9DneQ/B56SNIkSZdKGk7y/O+i89dzZLrurvRs73AS+h3ApyVNlTQWuK6b9u1fs5FpfFtIflf8m27Wf4jkOK6VNFDSfJKz9Fb/CCxMz34labiSjjutX/w6/f9jR85JrgRFxCaSy2V/lSaf+STfkDeRfNv8PB2/N75K8uP5duCXwN3tlt8A/M/0UsznOlj/apJvw+uBn5D8lvTbIkIeAtxI0sniRWBiGu+R+BnJpbKtwDUkv4Ud7Kb9MmA5yTH/E0BE/ITkbPK29FLWk8DFBetdD/zf9Llo7QF5P8kH5wOdTHe53fRS71uAq0iewxfTtkMO90kocD9JR5ffAd+MiN+k8/+eJEn8hiTJ/BMwtIP1PwF8TdJO4MvpOq2OBe5K13863de/kLy3/jI9hibg3HQ7HfkcSeLcSZIkbu+kXUf+keRy6QrgUV79fm2v/fv3VpJLnOuAp+j6yxDp2fllJF/etpFc6fgFSaIkIuqBjwHfI3n/rQI+2MX+rQfolZePzfJLSff2EyPiz/s6lr4mqZKXe5Y29200+SXpEWBRRPxzX8dSqnwmZ2bWQySdK+nY9HLlB0huq/h1X8dVyjJLcpJulrRR0pOdLJek7yi5KfhxSXOzisXMrJecTHJ5dDvJJdl3R8SGvg2ptGV2uVLSOSQ/KN8aEad1sPwS4FMk9/LMI7kZdl4mwZiZWUnK7EwuIh4g+VG5M/NJEmBExMPAGEmvujfLzMzsSPXlb3JTeOWNko10fiOtmZnZYevLukod3dDZ4bVTSQuABQDDhw8/c+bMDgdHMDOzErVs2bLNETGh/fy+THKNvHI0gE5HnoiIxcBigOrq6qivr88+OjMz6zckdThsW19erlwCvD/tZXkWsN29kMzMrCdldiYn6UckgwGPl9QIfIWk/AQRsQi4h6Rn5SqSQVU/lFUsZmZWmjJLchFxdTfLA/hkVvs3MzPziCdmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbmSY5SRdJelbSKknXdbB8rKSfSHpc0lJJp2UZj5mZlZbMkpykMuAm4GJgFnC1pFntmn0JWB4Rs4H3A9/OKh4zMys9WZ7J1QKrIuL5iDgA3AbMb9dmFvA7gIh4BqiUNCnDmMzMrIRkmeSmAA0F043pvEIrgMsAJNUC04GpGcZkZmYlJMskpw7mRbvpG4GxkpYDnwIeA5pftSFpgaR6SfWbNm3q+UjNzCyXBma47UagomB6KrC+sEFE7AA+BCBJwOr0j3btFgOLAaqrq9snSjMzsw5leSZXB8yQVCVpMHAVsKSwgaQx6TKAjwIPpInPzMzsNcvsTC4imiVdC9wLlAE3R8RKSQvT5YuAU4BbJR0CngI+klU8ZmZWerK8XElE3APc027eooLHDwEzsozBzMxKl0c8MTOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3HKSMzOz3Mo0yUm6SNKzklZJuq6D5aMl/VzSCkkrJX0oy3jMzKy0ZJbkJJUBNwEXA7OAqyXNatfsk8BTEXEGcB7wvyUNziomMzMrLVmeydUCqyLi+Yg4ANwGzG/XJoCRkgSMAJqA5gxjMjOzEpJlkpsCNBRMN6bzCn0POAVYDzwBfCYiWtpvSNICSfWS6jdt2pRVvGZmljNZJjl1MC/aTb8VWA5MBuYA35M06lUrRSyOiOqIqJ4wYULPR2pmZrmUZZJrBCoKpqeSnLEV+hBwdyRWAauBmRnGZGZmJSTLJFcHzJBUlXYmuQpY0q7NC8AFAJImAScDz2cYk5mZlZCBWW04IpolXQvcC5QBN0fESkkL0+WLgK8Dt0h6guTy5hciYnNWMZmZWWnJLMkBRMQ9wD3t5i0qeLweeEuWMZiZWenyiCdmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbTnJmZpZbmSY5SRdJelbSKknXdbD885KWp39PSjokqTzLmMzMrHRkluQklQE3ARcDs4CrJc0qbBMRfxcRcyJiDvBF4P6IaMoqJjMzKy1ZnsnVAqsi4vmIOADcBszvov3VwI8yjMfMzEpMlkluCtBQMN2YznsVScOAi4AfZxiPmZmVmCyTnDqYF520fQfwn51dqpS0QFK9pPpNmzb1WIBmZpZvWSa5RqCiYHoqsL6TtlfRxaXKiFgcEdURUT1hwoQeDNHMzPIsyyRXB8yQVCVpMEkiW9K+kaTRwLnAzzKMxczMStDArDYcEc2SrgXuBcqAmyNipaSF6fJFadN3Ab+JiN1ZxWJmZqVJEZ39THZ0qq6ujvr6+r4Ow8zMjiKSlkVEdfv5HvHEzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyy0nOzMxyq9skJ+mNxcwzMzM72hRzJvfdIueZmZkVZf22vfxs+TruWtaY6X46LZoq6fXAG4AJkv6iYNEokiKoZmZm3YoIntu0m7o1TdStbuKR1U2s27YXgFOOG8W7z5ya2b67qgw+GBiRthlZMH8H8O7MIjIzs36t+VALT2/YydI0qdWtaWLL7gMAjB8xmNqqcj76Z1XUVpUz89hRmcbSaZKLiPuB+yXdEhFrJQ2PiN2ZRmNmZv3OvoOHeLxxO0tXb2Hpmq08unYru/Y3A1BRPpRzT57AvKpyairLqRo/HEm9FltXZ3KtJkv6FclZ3TRJZwAfj4hPdLeipIuAb5Nc3vxBRNzYQZvzgG8Bg4DNEXHuYcRvZma9bOe+gyxbu5Wl6VnaiobtHDjUAsDJk0byztdNprZqHLWV5Rw7+pg+jbWYJPct4K3AEoCIWCHpnO5WklQG3ARcCDQCdZKWRMRTBW3GAN8HLoqIFyRNPIJjMDOzDG3etZ+61U0sXdPE0tVNPL1hBy0BAweI06aM5oNvrKSmspzq6WMZO3xwX4f7CsUkOSKiod3p5aEiVqsFVkXE8wCSbgPmA08VtHkvcHdEvJDuZ2Mx8ZiZWTYigsate9vO0pauaeL5TckvVccMGsDrKsbyqfNnUFtVzuumjWHY4KLSSJ8pJroGSW8AQtJg4NPA00WsNwVoKJhuBOa1a3MSMEjSfSSdW74dEbcWsW0zM+sBLS3Bqk27eGT1y51ENmzfB8CoYwZSU1nOldUV1FSVc9rk0Qwe2L/GECkmyS0k+V1tCkmi+g3wySLW6+iXxehg/2cCFwBDgYckPRwRf3rFhqQFwAKAadOmFbFrMzPryMFDLaxcv6OtK3/92ia27TkIwKRRQ6ipLKe2Kvk7aeJIBgzovU4iWeg2yUXEZuB9R7DtRqCiYHoqsL6DNpvTXpu7JT0AnAG8IslFxGJgMUB1dXX7RGlmZp3Ye+AQjzVspW71VurWNPHoC1vZcyD5xalq/HDeMmtSW2KbVj6sV3s+9oZuk5yk73QweztQHxE/62LVOmCGpCpgHXAVyW9whX4GfE/SQJL78uYB/6eYwM3M7NW27zlI/dqmtnvUnli3nYOHAglmHjuKK6orqKksp6ZyLBNH9W3Px95QzOXKY4CZwJ3p9OXASuAjkt4UEZ/taKWIaJZ0LXAvyS0EN0fESkkL0+WLIuJpSb8GHgdaSG4zePK1HZKZWenYuGNfW6/HpaubePalnUTAoDIxe+oYPnL28cyrKmfu9LGMHjqor8PtdYro+uqfpN8Db4mI5nR6IMnvchcCT0TErMyjLFBdXR319fW9uUszs6NCRLB2y562s7Sla5pYu2UPAMMGl3Hm9LHpWVrS8/GYQaUzAqOkZRFR3X5+MWdyU4DhJJcoSR9PjohDkvb3YIxmZlagpSV45sWdbV3561Y3sXFn8rE7dtggairLueas6dRUlnPq5FEMLOtfPR97QzFJ7m+B5Wk3fwHnAH8jaTjw7xnGZmZWUg40t/DEuu1t96jVr2lix75keKzJo4/h9SeMS3o+VpZzwoQR/b7nY2/oMslJGkByT9wbSG7uFvCliGjtJfn5bMMzM8uv3fubeeyFbelvaltY3rCNfQeT4bFOmDCct80+rq3n49Sxw/o42v6pyyQXES2S/ndEvJ6kJ6SZmR2hrbsPJOVm0o4iT67fwaGWYIBg1uRRvLd2OrVVY6muLGf8iCF9HW4uFHO58jeSLicZfsv3qJmZFWn9tr1tCa1uTRN/emkXAIMHDmDO1DEsPPd4aqvGMXfaGEYeU3o9H3tDMUnuL0g6mzRL2kdyyTIiItsiQGZm/UhE8Pzm3Umvx7TnY+PWpDDoiCEDOXP6WObPmUJtVTmnTxldUj0f+1IxI56M7K6NmVmpOdQSPL1hR9v9afVrm9i8KykMOm54Uhj0w29MCoOectwoytxJpE8UNXy0pLHADJIbwwGIiAeyCsrM7GjTWhi09fLjsoLCoFPHDuWckyZQW1lOTVU5x/dyYVDrXDHDen0U+AzJ2JPLgbOAh4Dzsw3NzKzv7Nx3kEdf2MbS1VuoW72V5Y3bONCc9Hw8adII5s+Z3DaQ8XGjh/ZxtNaZYs7kPgPUAA9HxJskzQS+mm1YZma9a/Ou/dSvSUbmr1vTxFPrk8KgZWlh0A+8fnrbaCJHW2FQ61wxSW5fROyThKQhEfGMpJMzj8zMLCOthUFbu/M/svrlwqBDBg5g7rSxXHv+DGrT4bGGDzm6C4Na54p55RoljQF+CvxW0lZeXTLHzOyo1VoYtLUrf93qJtYXFAatrixvG53/9Cn9rzCoda6Y3pXvSh9eL+kPwGjgV5lGZWb2GjSnhUFbu/LXr2lia1oYdOLIIdRUlfPxdCSRkyf1/8Kg1rliOp78MCKuAYiI+1vnAddkHJuZWVH2HTzEYy9sa+v5WFgYdPq4Ybz5lEnUpGM+Th+Xv8Kg1rliLleeWjghqQw4M5twzMy6t33vQZatbWJpWu368cZtbYVBT540knefOZXaqqSTyKQSKAxqnes0yUn6IvAlYKikHa2zgQPA4l6IzcwMeLkwaFJDbSvPvLijrTDo6VNG8+Gzq6itLKd6ejmjh3l4LHtZp0kuIm4AbpB0Q0R8sRdjMrMSFhG80LSnbSSRujVNrEkLgw4dlBQG/ewFJ1FTNZbXVYxl6GAPj2WdK6bjiROcmWWmpSV49qWdbb+nLS0oDDpm2CCqp5fzvnnTqalKCoMOcmFQOwyZ3vwh6SLg20AZ8IOIuLHd8vNISvisTmfdHRFfyzImM+tbrYVBW7vy1xUUBj1u9DGcdfy4tpFETnRhUHuNuvpNrioiVne2vDtpB5WbgAuBRqBO0pKIeKpd0z9GxNuPdD9mdnTbcyApDPrI6iSpPdawta0w6PEThnPJ6YWFQYe656P1qK7O5O4CzpT0u4i44Ai2XQusiojnASTdBswH2ic5M8uRbXsOULdmK0tXb2Hpmq2sXLed5rQw6CnHjeLq2mlJJ5HKciaMdGFQy1ZXSW6ApK8AJ0n6i/YLI+Lvu9n2FKChYLoRmNdBu9dLWkEyisrnImJlN9s1s6PIhu172zqILF1dUBi0bABnVIzm4+ceT01lOWdOH+vCoNbrukpyVwHvTNscSU25jq45tK8s/igwPSJ2SbqEZOiwGa/akLQAWAAwbdq0IwjFzHpCRLB68+62kUTq1jTR0PRyYdC508dy6RmTqa0ax+ypLgxqfa+rWwieBb4h6fGIOJJhvBqBioLpqbQb8zIidhQ8vkfS9yWNj4jN7dotJr03r7q6un2iNLOMFBYGbR3MuLAwaE1lOR98Q3KP2inHjWSgez7aUaaY3pUPSvp74Jx0+n7gaxGxvZv16oAZkqqAdSRnhu8tbCDpWOCliAhJtcAAYMvhHICZ9Zz9zUlh0Nau/I+u3crOtDDolDFDOWfGBGrSkUROmODCoHb0KybJ3Qw8CVyRTl8D/DNwWVcrRUSzpGuBe0luIbg5IlZKWpguXwS8G/hvkpqBvcBVEeEzNbNesmt/M8vWbk1HEmliecPLhUFnTBzBO+ZMZl6a1CaPcWFQ63/UXU6RtDwi5nQ3r7dUV1dHfX19X+zarN/bsmt/2kEkGfNx5frtLxcGnTwqKQqaJrVyFwa1fkTSsoiobj+/mDO5vZLOjoj/SDf0RpKzLjM7yjVu3fOKkUSeKygMOqdiDNe+6URqqsqZO22sC4NaLhXzrl4I3CppdDq9FfhAdiGZ2ZGICFZt3PXyQMYFhUFHHjOQ6uljufzMqcyrKue0KaMZMtA9Hy3/ihm7cgVwhqRR6fSOblYxs17QWhi09Uytfu1WmnYnPR8njBxCbWU5CyrHUlNVzsxjR1Hm4bGsBBV9fcLJzaxv7Tt4iOUN29q68z+6diu708Kg08qHcf7MidSmv6lVujCoGZDxAM1mduR27DvIsjVbWZqeqbUvDHrZ3KltAxm7MKhZx5zkzI4SG3fuoy7t9fjI6qa2wqADB4jTp47mw2+sorbKhUHNDkdRSU7SG4DKwvYRcWtGMZnlXkTQ0LSXR1ZvSUcS2crqzUnPx6GDypg7fQyfuWAGtZXlzJk2hmGD/X3U7Eh0+z9H0g+BE4DlwKF0dgBOcmZFamkJ/rRxJ3Wrk7O0ujVNvLQjKQw6euggairHcnVtBTWVSc9HFwY16xnFfD2sBmZ5JBKz4h08lBYGXf1yz8ftew8CcOyoY6itSguDVpYzY6ILg5plpZgk9yRwLLAh41jM+q3WwqBtPR9fKCgMOn44F516LDVV5cxzYVCzXlVMkhsPPCVpKbC/dWZEXJpZVGZHuW17DlBf0PPxybQwqASnHDuKq2qmJZ1EKscycaR7Ppr1lWKS3PVZB2F2tHtx+740oW2hbvVWnn1pJ5AUBp09dTQfO+d4aquSwqCjXBjU7KhRzIgn9/dGIGZHi9bCoK0DGS9ds6WtMOjwwWXMnT6Wt88+jpqqcuZUjHFhULOjWDG9K88CvgucAgwmKZuzOyJGZRybWa9oLQzaWhR06eqtbN6VXJkvHz6YmsqxfOD1ldRWlTPruFEuDGrWjxRzufJ7JAVP7yTpafl+YEaWQZllaX/zIZ5o3N7WlX/ZmlcWBj37xHFp78exnDBhhDuJmPVjRd1hGhGrJJVFxCHgnyU9mHFcZj1m1/5mHl378kgiKxq2sT8tDHrixBG8/YzJ1FaNpaaynKljh/VxtGbWk4pJcnskDQaWS/pbklsJhmcbltmRSwqDbm27/Lhy/Q4OtQQDBKdNGc2fnzU9KQ5aOZZxI4b0dbhmlqFiktw1wADgWuD/AyqAy7MMyuxw7dx3kJ+v2MAd9Q0sb9gGwOC0MOgnzjuBmspy5k4fywgXBjUrKcX0rlwraShwXER89XA2Luki4NsknVV+EBE3dtKuBngYuDIi7jqcfVjpigiWrm7i9voG7nliA/sOtnDSpBF87i0ncdbx4zh9qguDmpW6YnpXvgP4JknPyipJc4CvdXczuKQy4CbgQqARqJO0JCKe6qDdN4B7j+wQrNRs3LGPux5t5M76RlZv3s2IIQN51+umcmVNBWdMHe2OImbWptibwWuB+wAiYrmkyiLWqwVWRcTzAJJuA+YDT7Vr9yngx0BNMQFbaTp4qIU/PLORO+ob+MOzmzjUEtRWlvPJN53IJacf61H6zaxDxXwyNEfE9iP4djwFaCiYbgTmFTaQNAV4F3A+TnLWgec27eKOugZ+/Og6Nu/az4SRQ1hwzvG858ypHD9hRF+HZ2ZHuaIGaJb0XqBM0gzg00AxtxB0lBXbVzL4FvCFiDjUVRKVtABYADBt2rQidm392e79zfzyiQ3cUddA/dqtlA0Q58+cyJXVFZx38gTfjG1mRSsmyX0K+B8kgzP/iOS3s68XsV4jSU/MVlOB9e3aVAO3pQluPHCJpOaI+Glho4hYDCwGqK6udsmfHIoIHmvYxh11Dfx8xXp2HzjE8eOHc93FM7ls7hQPcmxmR6SY3pV7SJLc/zjMbdcBMyRVAetIRk15b7ttV7U+lnQL8Iv2Cc7ybfOu/fz0sXXcXtfAf23cxdBBZbxt9nFcWVNB9fSx7kRiZtbn9VUAABA6SURBVK9Jp0lO0pKuVuyud2VENEu6luTMrwy4OSJWSlqYLl90BPFaDhxqCR740yZur2vg359+ieaWYE7FGG647HTePvs4RnoUfzPrIV2dyb2epOPIj4BH6Pg3ti5FxD3APe3mdZjcIuKDh7t9619e2LKHO+obuGtZIy/u2Ef58MF88A2VXFFTwUmTRvZ1eGaWQ10luWNJ7nG7muQy4y+BH0XEyt4IzPJh38FD/PrJF7m9roGHnt/CAME5J03gK++YxQWnTGLwQHciMbPsdJrk0sGYfw38WtIQkmR3n6SvRcR3eytA638igifX7eD2+hf42fL17NzXzLTyYXzuLSdx+ZlTOW700L4O0cxKRJcdT9Lk9jaSBFcJfAe4O/uwrD/atudA0omkvpGnN+xgyMABXHzasVxRU8FZVeMYMMCdSMysd3XV8eT/AqcBvwK+GhFP9lpU1m+0tAQPPreF2+sbuHflixxobuG0KaP4+vxTufSMKYwe5k4kZtZ3ujqTuwbYDZwEfLqgK7eAcGXw0rZu217uqm/kzmUNNG7dy+ihg7i6poIraio4dfLovg7PzAzo+jc59wiwV9jffIjfPvUSt9c18B+rNhMBZ584nv9+0UzeMmsSxwzyiP9mdnTxqLbWrWde3MHtdQ389LF1bN1zkMmjj+FT58/gPWdOpaLclbTN7OjlJGcd2rHvID9fsZ476hpY0bidQWXiLbOSTiRnnzieMnciMbN+wEnO2kQEj6xu4o66Bu55MilCevKkkfzV22fxrtdNoXz44L4O0czssDjJGS/t2Mddyxq5s76BNVv2MHLIQC6bO5UrqyuY7SKkZtaPOcmVqIOHWvj9Mxu5o66B+/6UFiGtKudT58/gktOPY+hgdyIxs/7PSa7ErNq4izvrXy5COjEtQnpFdQVV44f3dXhmZj3KSa4E7N7fzC8f38Dt9Q0sW7uVga1FSGsqOPckFyE1s/xyksupiODRF5IipL94PC1COmE4X7x4JpfNncqEkUP6OkQzs8w5yeXM5l37+cmj67i9voFVG3cxbHAZbzs9KUJ6pouQmlmJcZLLgY6KkM6dNoYbLzudt58xmRFD/DKbWWnyp18/tnbLbu6ob+DHy9bx4o59jBs+mA+9sZIrqiuY4SKkZmZOcv3NvoOH+NWTG7i9roGHn29igODckyZw/aWzOH+mi5CamRXKNMlJugj4NlAG/CAibmy3fD7wdaAFaAY+GxH/kWVM/VFE8MS67dxR3+AipGZmhyGzJCepDLgJuBBoBOokLYmIpwqa/Q5YEhEhaTZwBzAzq5j6m217DvCTx9Zxe10Dz7y4kyEDB3DJ6cdxRXUF86rKXYTUzKwbWZ7J1QKrIuJ5AEm3AfOBtiQXEbsK2g8HIsN4+oWWluA/n9vM7XUN/GblSxw41MLpU0bz9XeexqVnTGb0UBchNTMrVpZJbgrQUDDdCMxr30jSu4AbgInA2zKM56i2btte7qxv4M76RtZtS4qQvnfeNK6ormDWZNenNTM7ElkmuY6upb3qTC0ifgL8RNI5JL/PvflVG5IWAAsApk2b1sNh9p32RUghKUL6hYtdhNTMrCdkmeQagYqC6anA+s4aR8QDkk6QND4iNrdbthhYDFBdXd3vL2k+vSEtQrp8Hdv2HGTKmKF8+vwZvNtFSM3MelSWSa4OmCGpClgHXAW8t7CBpBOB59KOJ3OBwcCWDGPqMzv2HWTJ8vXcUd/A443bGVw2gAtPncSV1RW80UVIzcwykVmSi4hmSdcC95LcQnBzRKyUtDBdvgi4HHi/pIPAXuDKiOj3Z2qtOipCOvPYkXw5LUI61kVIzcwypf6WU6qrq6O+vr6vw+hSR0VIL50zmStrKjh9iouQmpn1NEnLIqK6/XyPeNJDDh5q4XdPb+SO+gbue3YjLQHzqsr59AUzuPg0FyE1M+sLTnKv0aqNu7ijvoG7H21k864DTBw5hIXnnsAV1RVUugipmVmfcpI7Ah0VIb3glIlcUe0ipGZmRxMnuSIlRUi3cntdA794fAN7DhzihAnD+dIlM3nX61yE1MzsaOQk143Nu/Zz96ON3FHf2FaE9O2zkyKkc6e5CKmZ2dHMSa4DzYdaeOC/kiKkv3t6Y1sR0m9cfjpvm+0ipGZm/YU/rQus2bybO5c1cNeyRl7asZ/xIwbz4bOruKJ6KidOdBFSM7P+puST3N4DLxchfWR1UoT0vJMn8tVLK7jglIkMcicSM7N+qySTXGsR0tvrGliyfD079zczfdwwPv/Wk7l87lSOHX1MX4doZmY9oOSSXERw5eKHWbq6iWMGDeCS047jPS5CamaWSyWX5CRx4SmTuPSMyVw6ZzKjjnERUjOzvCq5JAfwsXOO7+sQzMysF7hXhZmZ5ZaTnJmZ5ZaTnJmZ5ZaTnJmZ5ZaTnJmZ5ZaTnJmZ5ZaTnJmZ5VamSU7SRZKelbRK0nUdLH+fpMfTvwclnZFlPGZmVloyS3KSyoCbgIuBWcDVkma1a7YaODciZgNfBxZnFY+ZmZWeLM/kaoFVEfF8RBwAbgPmFzaIiAcjYms6+TAwNcN4zMysxGSZ5KYADQXTjem8znwE+FVHCyQtkFQvqX7Tpk09GKKZmeVZlkmuoyH9o8OG0ptIktwXOloeEYsjojoiqidMmNCDIZqZWZ5lOUBzI1BRMD0VWN++kaTZwA+AiyNiS4bxmJlZicnyTK4OmCGpStJg4CpgSWEDSdOAu4FrIuJPGcZiZmYlKLMzuYholnQtcC9QBtwcESslLUyXLwK+DIwDvi8JoDkiqrOKyczMSosiOvyZ7KhVXV0d9fX1fR2GmZkdRSQt6+gkySOemJlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbmWa5CRdJOlZSaskXdfB8pmSHpK0X9LnsozFzMxKz8CsNiypDLgJuBBoBOokLYmIpwqaNQGfBt6ZVRxmZla6sjyTqwVWRcTzEXEAuA2YX9ggIjZGRB1wMMM4zMysRGWZ5KYADQXTjek8MzOzXpFlklMH8+KINiQtkFQvqX7Tpk2vMSwzMysVWSa5RqCiYHoqsP5INhQRiyOiOiKqJ0yY0CPBmZlZ/mWZ5OqAGZKqJA0GrgKWZLg/MzOzV8isd2VENEu6FrgXKANujoiVkhamyxdJOhaoB0YBLZI+C8yKiB1ZxWVmZqUjsyQHEBH3APe0m7eo4PGLJJcxzczMepxHPDEzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9xykjMzs9zKNMlJukjSs5JWSbqug+WS9J10+eOS5mYZj5mZlZbMkpykMuAm4GJgFnC1pFntml0MzEj/FgD/kFU8ZmZWerI8k6sFVkXE8xFxALgNmN+uzXzg1kg8DIyRdFyGMZmZWQnJMslNARoKphvTeYfbxszM7IgMzHDb6mBeHEEbJC0guZwJsEvSs68xttdiPLC5D/efNR9f/5f3Y/Tx9W9ZHd/0jmZmmeQagYqC6anA+iNoQ0QsBhb3dIBHQlJ9RFT3dRxZ8fH1f3k/Rh9f/9bbx5fl5co6YIakKkmDgauAJe3aLAHen/ayPAvYHhEbMozJzMxKSGZnchHRLOla4F6gDLg5IlZKWpguXwTcA1wCrAL2AB/KKh4zMys9WV6uJCLuIUlkhfMWFTwO4JNZxpCBo+KyaYZ8fP1f3o/Rx9e/9erxKckzZmZm+eNhvczMLLec5DrR3ZBkBe1qJB2S9O7ejO+1Kub4JJ0nabmklZLu7+0YX4sihpQbLennklakx9evfg+WdLOkjZKe7GR5vx4yr4jje196XI9LelDSGb0d42vR3fEVtOuvny/dHl+vfb5EhP/a/ZF0lHkOOB4YDKwAZnXS7vckvzu+u6/j7snjA8YATwHT0umJfR13Dx/fl4BvpI8nAE3A4L6O/TCO8RxgLvBkJ8svAX5Fci/qWcAjfR1zDx/fG4Cx6eOL83Z8aZt++flS5OvXa58vPpPrWDFDkgF8CvgxsLE3g+sBxRzfe4G7I+IFgIjoT8dYzPEFMFKSgBEkSa65d8M8chHxAEnMnenXQ+Z1d3wR8WBEbE0nHya5x7bfKOL1g/77+VLM8fXa54uTXMe6HW5M0hTgXcAi+p9ihlM7CRgr6T5JyyS9v9eie+2KOb7vAaeQDD7wBPCZiGjpnfB6RSkNmfcRkrPW3Ojnny/F6LXPl0xvIejHihlu7FvAFyLiUHIy0K8Uc3wDgTOBC4ChwEOSHo6IP2UdXA8o5vjeCiwHzgdOAH4r6Y8RsSPr4HpJUUPm9XeS3kSS5M7u61h6WH/+fClGr32+OMl1rJjhxqqB29I34HjgEknNEfHT3gnxNSl2yLXNEbEb2C3pAeAMoD8kuWKO70PAjZH8ILBK0mpgJrC0d0LMXFFD5vVnkmYDPwAujogtfR1PD+vPny/F6LXPF1+u7Fi3Q5JFRFVEVEZEJXAX8Il+9AYsZsi1nwF/JmmgpGHAPODpXo7zSBVzfC+QfItE0iTgZOD5Xo0yW7keMk/SNOBu4Jp+cnXhsPTzz5di9Nrni8/kOhDFDUnWbxVzfBHxtKRfA48DLcAPIqLL7s5HiyJfv68Dt0h6guTS3hciot+M/C7pR8B5wHhJjcBXgEGQjyHziji+LwPjgO+nZzvN0Y8GNS7i+Pq17o6vNz9fPOKJmZnlli9XmplZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmZlZbjnJmfWxdJT55ZKelHRnet9QZ22vl/S53ozPrD9zkjPre3sjYk5EnAYcABb2dUBmeeEkZ3Z0+SNwIoCk96f10lZI+mH7hpI+JqkuXf7j1jNASe9JzwpXpMMlIelUSUvTM8bHJc3o1aMy6yO+Gdysj0naFREjJA0kKa3ya+ABkmGr3hgRmyWVR0STpOuBXRHxTUnjWsdslPTXwEsR8d10FJeLImKdpDERsU3Sd4GHI+Jf06HOyiJib58csFkv8pmcWd8bKmk5UE8ypuY/kVRHuKt1qLGI6Kg212mS/pgmtfcBp6bz/5NkyLKPkQxrBvAQ8CVJXwCmO8FZqfDYlWZ9b29EzCmckRZz7e4yyy3AOyNihaQPkowVSEQslDQPeBuwXNKciPg3SY+k8+6V9NGI+H0PH4fZUcdncmZHp98BV0gaByCpvIM2I4ENkgaRnMmRtj0hIh6JiC8Dm4EKSccDz0fEd0gqFMzO/AjMjgI+kzM7CqVVE/4XcL+kQ8BjwAfbNfsr4BFgLUl185Hp/L9LO5aIJFmuAK4D/lzSQeBF4GuZH4TZUcAdT8zMLLd8udLMzHLLSc7MzHLLSc7MzHLLSc7MzHLLSc7MzHLLSc7MzHLLSc7MzHLLSc7MzHLr/wGIQkfJlYC9pwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "''' The PRatioEncoder(encoding_method='ratio' or 'log_ratio') has the characteristic that return monotonic\n",
    " variables, that is, encoded variables which values increase as the target increases'''\n",
    "\n",
    "# let's explore the monotonic relationship\n",
    "plt.figure(figsize=(7,5))\n",
    "pd.concat([test_t,y_test], axis=1).groupby(\"pclass\")[\"survived\"].mean().plot()\n",
    "#plt.xticks([0,1,2])\n",
    "plt.yticks(np.arange(0,1.1,0.1))\n",
    "plt.title(\"Relationship between pclass and target\")\n",
    "plt.xlabel(\"Pclass\")\n",
    "plt.ylabel(\"Mean of target\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Automatically select the variables\n",
    "\n",
    "This encoder will select all categorical variables to encode, when no variables are specified when calling the encoder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PRatioEncoder(encoding_method='log_ratio',\n",
       "              variables=['pclass', 'sex', 'cabin', 'embarked'])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_t = rare_encoder.transform(X_train)\n",
    "test_t = rare_encoder.transform(X_test)\n",
    "\n",
    "logRatio_enc = PRatioEncoder(encoding_method='log_ratio')\n",
    "\n",
    "# to fit you need to pass the target y\n",
    "logRatio_enc.fit(train_t, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pclass</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>fare</th>\n",
       "      <th>cabin</th>\n",
       "      <th>embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1270</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>-1.465631</td>\n",
       "      <td>28.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>9.5000</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1078</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>0.986309</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.8792</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.517257</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>828</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>0.986309</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5</td>\n",
       "      <td>2</td>\n",
       "      <td>46.9000</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>601</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>-1.465631</td>\n",
       "      <td>13.0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>20.2500</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>936</th>\n",
       "      <td>-1.050984</td>\n",
       "      <td>0.986309</td>\n",
       "      <td>26.0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>22.0250</td>\n",
       "      <td>-0.824339</td>\n",
       "      <td>-0.667945</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        pclass       sex   age  sibsp  parch     fare     cabin  embarked\n",
       "1270 -1.050984 -1.465631  28.0      0      0   9.5000 -0.824339 -0.667945\n",
       "1078 -1.050984  0.986309   NaN      0      0   7.8792 -0.824339 -0.517257\n",
       "828  -1.050984  0.986309  10.0      5      2  46.9000 -0.824339 -0.667945\n",
       "601  -1.050984 -1.465631  13.0      0      2  20.2500 -0.824339 -0.667945\n",
       "936  -1.050984  0.986309  26.0      1      1  22.0250 -0.824339 -0.667945"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# transform and visualise the data\n",
    "\n",
    "train_t = logRatio_enc.transform(train_t)\n",
    "test_t = logRatio_enc.transform(test_t)\n",
    "\n",
    "test_t.sample(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
